# import os
#
# from docx import Document
# from docx import Document
# from docx.shared import Inches,Pt
# from docx.oxml import OxmlElement
# from docx.oxml.ns import qn
# from lxml import etree
# import io
# import shutil
# import re
# from docx import Document
# from docx.shared import RGBColor
# from lxml import etree
# from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
# from docx.enum.text import WD_UNDERLINE
# import requests
# import json_repair
# import json
#
# # 定义命名空间
# namespaces = {
#     'w': 'http://schemas.openxmlformats.org/wordprocessingml/2006/main',
#     'a': 'http://schemas.openxmlformats.org/drawingml/2006/main',
#     'r': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'
# }
#
# #调用大模型
# def dify_chat(query):
#     # global pool_sema
#     # # 开启线程限制
#     # with pool_sema:
#     url = 'http://192.168.43.12:8083/v1/chat-messages'  # v1/chat-messages'调用聊天框  workflows/run智能体
#     api_key = 'app-E5OKzE323dg4s4g8T8lwmG40'  # 'app-ldimOhba65Dq5BlHpPXQaDka'  # 替换为您的实际API密钥
#
#     # 请求头
#     headers = {
#         'Authorization': f'Bearer {api_key}',
#         'Content-Type': 'application/json'
#     }
#
#     # 请求数据
#     data = {
#         "inputs": {},
#         "query": query,
#         "response_mode": "streaming",  # blocking streaming
#         "conversation_id": "",
#         "user": "abc-123",
#     }
#
#     # 将数据转换为JSON字符串
#     data_json = json.dumps(data)
#
#     answer = ''
#
#     # 发送GET请求，并设置stream=True
#     with requests.post(url, headers=headers, data=data_json.encode("utf-8"), stream=True) as r:
#         # 检查请求是否成功
#         r.raise_for_status()
#
#         # 打印每一行文本
#         for line in r.iter_lines():
#
#             # 忽略保持连接的空行
#             if line:
#                 # 解码每一行，因为返回的数据可能是字节串
#                 line = line.decode('utf-8')
#                 if 'data: ' in line:
#                     data = json.loads(line.replace('data: ', ''))
#                     if data['event'] == 'message':
#                         # print(data['answer'])
#                         answer += data['answer']
#                         print(data['answer'],end='')
#                     elif data['event'] == 'message_end':
#                         break
#
#     #去除思考过程
#     answer = answer.split('</think>')[-1]
#
#     return answer
#
# #获取大模型json结果
# def json_process(data_answ):
#     pattern = r'```json(.*?)```'
#     matches = re.findall(pattern, data_answ, re.DOTALL)  # 抽取出内容并判断长度
#     if matches:
#         c_statement = json_repair.loads(matches[-1])
#         # print("\n-------step2查到的对应的内容为：\n", c_statement)
#     else:
#         c_statement = {}
#     # decoded_object = json_repair.loads(c_statement)
#     # return json.dumps(decoded_object,ensure_ascii=False)
#     return c_statement
#
# def copy_paragraph_from_doc_to_doc(source_paragraph, target_document):
#     # 创建一个新的段落
#     # if source_paragraph.text:
#     new_paragraph = target_document.add_paragraph()
#
#     # 复制段落样式
#     new_paragraph.style = source_paragraph.style
#
#     # 遍历源段落中的所有运行（运行包含文本和样式）
#     for run in source_paragraph.runs:
#         # 添加运行到新段落
#         new_run = new_paragraph.add_run(run.text)
#
#         # 复制运行样式
#         new_run.font.name = run.font.name
#         new_run.font.size = run.font.size
#         new_run.font.bold = run.font.bold
#         new_run.font.italic = run.font.italic
#         new_run.font.underline = run.font.underline
#         new_run.font.color.rgb = run.font.color.rgb
#
#         # 复制段落格式
#         new_paragraph.alignment = source_paragraph.alignment
#
# def copy_element_style(element,doc,new_doc):
#     if element.tag.endswith('p'):  # 段落
#
#         #段落文本
#         para_text = ''
#         judge = False
#
#         para = {'para': {}, 'runs': [], 'pad': False, "pad_num": 0}
#
#         # 提取段落中的所有文本
#         element_xml = etree.fromstring(element.xml)
#         # p = new_doc.add_paragraph()
#         e_list_tem=[el for el in doc.element.body.inner_content_elements if "tbl" not in str(el)]
#         # print("e_list_tem:",len(e_list_tem))
#         # print(len(doc.paragraphs))
#         paragraph = doc.paragraphs[e_list_tem.index(element)]
#         # 获取段前段后间距
#         # p.paragraph_format.space_before = paragraph.paragraph_format.space_before
#         # p.paragraph_format.space_after = paragraph.paragraph_format.space_after
#         # print("段前段后：",p.paragraph_format.space_before,p.paragraph_format.space_after)
#         para['para']['space_before'] = paragraph.paragraph_format.space_before
#         para['para']['space_after'] = paragraph.paragraph_format.space_after
#
#         #设置首行缩进
#         # p.paragraph_format.first_line_indent=paragraph.paragraph_format.first_line_indent
#         para['para']['first_line_indent'] = paragraph.paragraph_format.first_line_indent
#
#         # 提取段落对齐方式
#         #  <w:pPr> <w:jc w:val="center"/>
#         align = element_xml.xpath('.//w:pPr/w:jc/@w:val', namespaces=namespaces)
#         if align:
#             alignment = WD_PARAGRAPH_ALIGNMENT.from_xml(align[0])
#             # p.alignment = alignment
#             para['para']['alignment'] = alignment
#
#         for run in element_xml.xpath('.//w:r', namespaces=namespaces):
#             mid = {}
#             # 提取run中的文本
#             run_text = "".join(run.xpath('.//w:t/text()', namespaces=namespaces))
#
#             #给大模型的文本，如果有下划线且为空，则将空置换为_
#             llm_text = run_text
#             print(f"文本：\t{[run_text]}")
#
#
#             # new_doc.add_paragraph(run_text)
#             # r = p.add_run(run_text)
#
#             # 提取并应用字体样式
#             print("提取并应用字体样式:", run.xpath('.//w:rPr/w:rFonts/@w:ascii', namespaces=namespaces))
#             if run.xpath('.//w:rPr/w:rFonts/@w:ascii', namespaces=namespaces):
#                 # r.font.name = run.xpath('.//w:rPr/w:rFonts/@w:ascii', namespaces=namespaces)[0]
#                 # r._element.rPr.rFonts.set(qn('w:eastAsia'), r.font.name)
#                 aaa = run.xpath('.//w:rPr/w:rFonts/@w:ascii', namespaces=namespaces)[0]
#                 #字体样式
#                 mid['font_name'] = run.xpath('.//w:rPr/w:rFonts/@w:ascii', namespaces=namespaces)[0]
#             else:
#                 #默认为宋体
#                 mid['font_name'] = '宋体'
#
#             # 提取并应用字体大小
#             size = run.xpath('.//w:rPr/w:sz/@w:val', namespaces=namespaces)
#             if size:
#                 # r.font.size = Pt(int(size[0]) / 2)  # docx中的大小单位是磅，而XML中通常是半点
#                 mid['font_size'] = Pt(int(size[0]) / 2)  # docx中的大小单位是磅，而XML中通常是半点
#
#             # 提取并应用字体颜色
#             color = run.xpath('.//w:rPr/w:color/@w:val', namespaces=namespaces)
#             if color:
#                 print("color:",color) #color=["auto"]
#                 if color[0].lower() == "auto":
#                     # 处理 "auto" 颜色值，例如使用默认颜色或指定一个颜色
#                     # 这里我们使用黑色作为示例
#                     # r.font.color.rgb = RGBColor(0, 0, 0)  # 黑色的RGB值
#                     font_color = RGBColor(0, 0, 0)  # 黑色的RGB值
#                 else:
#                     # r.font.color.rgb = RGBColor.from_string(color[0])
#                     font_color = RGBColor.from_string(color[0])
#                 mid['font_color'] = font_color
#                 # # 提取并应用加粗样式 因为有些文本有的加粗有的不加粗 这里先暂时不弄
#             # bold = run.xpath('.//w:rPr/w:b', namespaces=namespaces)
#             # if bold:
#             #     r.font.bold = True
#             # 检查是否有下划线属性
#             underline = run.xpath('.//w:rPr/w:u/@w:val', namespaces=namespaces)
#             # print(underline)
#             # 如果存在下划线属性，获取其值，否则默认为None
#             underline_val = underline[0] if underline and underline[0]!="none" else None
#             # print("underline_val:",underline_val)
#             # 如果underline_val不为None，则设置下划线
#             if underline_val is not None and str(underline_val) is not "none":
#                 # 在docx中，underline可以是True、False或者下划线类型的字符串
#                 # 例如 'single', 'double', 'thick', 'dotted' 等
#                 # 这里将underline_val直接作为参数传递，假设它是一个有效的下划线类型
#                 underline_enum = getattr(WD_UNDERLINE, underline_val.upper(), None)
#                 # r.underline = underline_enum
#                 # r_underline = r.underline
#                 mid['underline'] = underline_enum
#                 para['pad'] = True
#                 print("r.underline",[run_text,underline_enum])
#             # for pic in run.xpath('.//w:drawing', namespaces=namespaces):
#             #     # pic是包含图片信息的XML元素
#             #     # 获取图片的RID
#             #     blip = pic.xpath('.//a:blip', namespaces=namespaces)
#             #     if blip:
#             #         # 假设blip是一个列表，通常情况下只有一个元素
#             #         blipRID = blip[0].attrib.get(qn('r:embed'))
#             #         # 这里可以处理blipRID，例如打印或者进行其他操作
#             #
#             #         # 添加图片到新文档
#             #         rel = doc.part.rels[blipRID]
#             #         image_part = doc.part.related_parts[blipRID].blob  # bytes
#             #         image_stream = io.BytesIO(image_part)
#             #         new_doc.add_picture(image_stream, width=Inches(1.25))
#
#             # # 给大模型的文本，如果有下划线且为空，则将空置换为_
#             if (not llm_text or set(llm_text) == set(' ')) and 'underline' in mid.keys():
#                 if llm_text:
#                     llm_text = llm_text.replace(' ','_')
#                 else:
#                     llm_text = '_'
#             para_text += llm_text
#             mid['text'] = llm_text
#
#             #如果为需填充下划线，判断是否要和前面拼到一起
#             if 'underline' in mid.keys():
#                 #如果为第一个，则直接添加
#                 if len(para['runs']) > 0:
#                     if 'underline' in para['runs'][-1].keys():
#                         para['runs'][-1]['text'] += llm_text
#                     else:
#                         para['runs'].append(mid)
#                         para['pad_num'] += 1
#                 else:
#                     para['runs'].append(mid)
#                     para['pad_num'] += 1
#             else:
#                 para['runs'].append(mid)
#
#         para['para']['text'] = para_text
#         # print('段落文本：', [para_text])
#         # if judge:
#         #     print('需要填充的文本：', [para_text])
#         return para
#
#     # elif element.tag.endswith('tbl'):  # 表格
#     #     # 提取表格内容
#     #     list_d = [i for i in doc.element.body.inner_content_elements if "<w:tbl>" in str(i)]
#     #     # print(list_d)
#     #     table = doc.tables[list_d.index(element)]
#     #
#     #     new_table = new_doc.add_table(rows=len(table.rows), cols=len(table.columns))
#     #     new_table.style = 'Table Grid'
#     #     try:
#     #         # 遍历原始表格的每一行和单元格
#     #         for row_idx, row in enumerate(table.rows):
#     #             for col_idx, cell in enumerate(row.cells):
#     #                 # 将单元格文本添加到新表格的相应单元格
#     #                 new_table.cell(row_idx, col_idx).text = cell.text.strip()
#     #     except Exception as e:
#     #         # 如果发生索引错误，打印错误信息并跳过当前行
#     #         print(f"Error: {e} encountered while processing row ")
#
# def copy_docx(source_path, target_path):
#     # 加载源文档
#     source_doc = Document(source_path)
#     # 创建目标文档
#     target_doc = Document()
#
#     # 遍历源文档中的所有段落
#     # for paragraph in source_doc.paragraphs:
#     #     copy_paragraph_from_doc_to_doc(paragraph, target_doc)
#     paras = []
#     for element in source_doc.element.body:
#         paras.append(copy_element_style(element,source_doc,target_doc))
#
#     #遍历paras，去除掉空的部分
#     paras = [para for para in paras if para]
#
#     # 给大模型的文本
#     llm_input_list = []
#     pad_num = 0
#
#     #遍历给大模型
#     for i, para in enumerate(paras):
#
#         mid_para = re.sub(r'[^\w\s]', '', para['para']['text'])
#
#         #如果全为空，先向前找文本
#         if set(' ') == set(mid_para) and para['pad']:
#             for past_para in paras[:i][::-1]:
#                 mid_past_para = re.sub(r'[^\w\s]', '', past_para['para']['text'])
#                 if set(' ') != set(mid_past_para) and mid_past_para:
#                     para['para']['text'] = f"{past_para['para']['text']}\n{para['para']['text']}"
#                     break
#
#
#         if para['pad']:
#             print('=================',[para['para']['text']])
#             llm_input_list.append(para['para']['text'])
#             pad_num += para['pad_num']
#
#     #如果需要大模型填充
#     if llm_input_list:
#         llm_input_text = '\n'.join(llm_input_list)
#         print(llm_input_text)
#         print(pad_num)
#         # result = ["标的2：数字化技术平台2024 年第五批采购项目", "南方电网数字企业科技(广东)有限公司", "2024", "12", "09"]
#         # result = ["南方电网数字企业科技(广东)有限公司", "曹旭", "男", 35, "董事长", "南方电网数字企业科技(广东)有限公司", "南方电网数字企业科技(广东)有限公司", "2024", "12", "09"]
#
#         #调用大模型获取结果
#         #提示词
#         prompt = '''
#         根据输入的信息，格式化文本中下划线位置需要填充的内容，返回格式为列表，以下为参考样例
#         <输入>
#         <文本>
#         标的名称:_____________
#         投标人：_____________________________（盖公章/电子印章）
#         ___年___月___日
#         </文本>
#         <填写数量>
#         5
#         </填写数量>
#         <信息>
#         {"标的名称": "标的1：项目1", "标包名称": "标包2：项目1", "投标人":"国网公司", "时间": "2025-05-02 11:52:33"}
#         </信息>
#         </输入>
#         <输出>
#         ```json
#         ["标的1：项目1", "国网公司", "2025", "05",  "02"]
#         ```
#         </输出>
#         '''
#         basic_info = {"标的名称": "标的2：数字化技术平台2024 年第五批采购项目", "标包名称": "标包1：北斗运营服务应用V3.0（安全升级改造）建设项目", "投标人":"南方电网数字企业科技(广东)有限公司", "时间": "2024-12-09 21:34:52", "法人姓名": "曹旭", "法人性别": "男", "法人年龄": 35, "法人职务": "董事长"}
#         llm_input_text = f'''
#         <文本>
#         {llm_input_text}
#         </文本>
#         <填写数量>
#         {pad_num}
#         </填写数量>
#         <信息>
#         {basic_info}
#         </信息>
#         '''
#         #调用大模型
#         query = f"{prompt}{llm_input_text}"
#         answer = dify_chat(query)
#
#         #将结果转为json
#         result = json_process(answer)
#
#         #填充原文本需要填充的部分
#         for para in paras:
#             if para['pad']:
#                 for run in para['runs']:
#                     if 'underline' in run.keys():
#
#                         run['text'] = f" {result[0]} "
#                         result = result[1:]
#
#         #填充到文档中
#         for para in paras:
#             #添加段落
#             p = target_doc.add_paragraph()
#
#             # 段前段后间距
#             p.paragraph_format.space_before = para['para']['space_before']
#             p.paragraph_format.space_after = para['para']['space_after']
#
#             # 设置首行缩进
#             p.paragraph_format.first_line_indent = para['para']['first_line_indent']
#
#             # 段落对齐方式
#             if 'alignment' in para['para'].keys():
#                 p.alignment = para['para']['alignment']
#
#             #段落内添加文本
#             for run in para['runs']:
#                 r = p.add_run(run['text'])
#
#                 #文本格式化
#                 #字体
#                 if 'font_name' in run.keys():
#                     r.font.name = run['font_name']
#                     r._element.rPr.rFonts.set(qn('w:eastAsia'), r.font.name)
#
#                 # 字号
#                 if 'font_size' in run.keys():
#                     r.font.size = run['font_size']  # docx中的大小单位是磅，而XML中通常是半点
#
#                 # 字体颜色
#                 if 'font_color' in run.keys():
#                     r.font.color.rgb = run['font_color']
#
#                 #下划线
#                 if 'underline' in run.keys():
#                     r.underline = run['underline']
#
#     # 保存目标文档
#     target_doc.save(target_path)
#
# # 使用函数
# # source_file ='./test/sample.docx'
# # target_file =  './general_docx/output.docx'
# # copy_docx(source_file, target_file)
# # source_file ='./s/'
# source_file ='/media/977GB/wcj_work/禅道/新视图开发/zentao/bid/generate/源文档'
# target_file = './生成文档/'
# if not os.path.isdir(target_file):
#     os.makedirs(target_file)
# source_files=os.listdir(source_file)
# for file in source_files:
#     if file.endswith("docx"):
#         file_name,f_ty=os.path.splitext(file)
#         source_path = os.path.join(source_file, file)
#         target_path=os.path.join(target_file,"testout_put"+file)
#         copy_docx(source_path, target_path)
# #可以提取到所有内容 问题 第一个样式获取文本 后面那个样式获取图片及其表格
#
# #如果现有表格数据会导致表格的位置在后面 位置错误了
# #第一个样式中读取表格及其图片数据
# #有个问题 下划线没实现 读取不到下划线

from docx import Document

doc = Document('/media/977GB/wcj_work/禅道/新视图开发/zentao/bid/文档/商务文件模板/1_商务_封面.docx')

# 遍历所有段落
for paragraph in doc.paragraphs:
    # 遍历段落内的所有Run
    for run in paragraph.runs:
        # 检查Run是否应用了下划线样式
        if run.font.underline:
            # 替换该Run的文本内容（保留原有下划线样式）
            # run.text = "要填充的新内容"
            print([run.text, '有下划线'])
        else:
            print([run.text, '无下划线'])

# 保存修改后的文档
doc.save("modified_document.docx")

